package com.lujianfei.powersearch

import org.junit.Assert
import org.junit.Test

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * @see [Testing documentation](http://d.android.com/tools/testing)
 */
class ExampleUnitTest {
    @Test
    fun addition_isCorrect() {
        Assert.assertEquals(4, (2 + 2).toLong())
    }

    @Test
    fun test_array() {
        val oldList = arrayListOf("1", "2", "3")
        val newList = arrayListOf("3", "4", "5")
        setData(oldList, newList)
        println("==========================")
        println(oldList)
        println("==========================")
    }

    @Test
    fun test_reverse_single_link() {

        val node1 = Node(text = "a")
        val node2 = Node(text = "b")
        val node3 = Node(text = "c", next = null)

        var header:Node? = node1
        node1.next = node2
        node2.next = node3

        // 输出反转前的结果
        var p:Node? = header
        while (p != null) {
            println(p.text)
            p = p.next
        }

        // 开始反转操作
        var beg:Node?= null
        var mid:Node? = header
        var end:Node? = header?.next

        while(true) {
            mid?.next = beg
            if (end == null) {
                break
            }
            // 整体向后移三个指针
            beg = mid
            mid = end
            end = end.next
        }
        header = mid

        // 输出反转后的结果
        p = header
        while (p != null) {
            println(p.text)
            p = p.next
        }
    }

    data class Node(var text:String = "", var next:Node?= null)

    private fun <M> setData(oldList: MutableList<M>, newList: MutableList<M>) {
        val newOldOffsetLen = newList.size - oldList.size

        val minSize = Math.min(oldList.size, newList.size)
        for (idx in 0 until minSize) {
            oldList[idx] = newList[idx]
        }
        if (newOldOffsetLen > 0) {
            oldList.addAll(newList.subList(oldList.size, newList.size))
        } else if (newOldOffsetLen < 0) {
            for (idx in oldList.size - 1 downTo newList.size) {
                oldList.removeAt(idx)
            }
        }
    }

    @Test
    fun test_question() {
//        println(split(originStr = "ab&&2", key = "&&"))
//        println(join(split(originStr = "ab&&2", key = "&&"), key = "&&"))
//        println(zhishu(n = 10))
        var totalStr = ""
        for (c in 'a' until 'c' + 1) {
            totalStr+= c
        }

        println(subsets(totalStr))
    }

    fun split(
        originStr: String,
        key: String
    ): List<String> {
        var currentOffset = 0
        var nextIndex = originStr.indexOf(key, currentOffset)
        if (nextIndex == -1) {
            return listOf(originStr)
        }
        val result = ArrayList<String>()
        do {
            result.add(originStr.substring(currentOffset, nextIndex))
            currentOffset = nextIndex + key.length
            // Do not search for next occurrence if we're reaching limit
            nextIndex = originStr.indexOf(key, currentOffset)
        } while (nextIndex != -1)

        result.add(originStr.substring(currentOffset, originStr.length))
        return result
    }

    fun join(list: List<String>, key: String): String {
        val buffer = StringBuffer()
        var idx = 0
        for (element in list) {
            buffer.append(element)
            if (++idx < list.size) buffer.append(key)
        }
        return buffer.toString()
    }

    fun zhishu(n: Int): List<Int> {
        val result = arrayListOf<Int>()
        //因为是不大于  所以从后往前遍历减少时间
        for (i in n downTo 2) {
            for (j in 2 until i) {
                if (i % j == 0) {
                    //余数为零不是质数直接跳过
                    //质数 只可以 1和自身整除
                    break;
                }
                if (j == i - 1) {
                    result.add(i)
                }
            }
        }
        //结束循环
        return result
    }

    fun find_in_1000(list:List<Int>):Int {
        list.sorted()
        for (i in 0 until list.size) {
            for (j in i + 1  until list.size) {
                if(list[i]==list[j]) {//相等则输出这个数并结束循环
                    return list[i]
                }
            }
        }
        return 0
    }

    fun johnson() {
        val ar =  arrayListOf<Int>();
        val n = 3
        val m = 4
        for (i in 0 until n) {
            ar.add(i + 1);
        }
        while (ar.size !=0 ){
            var order = m % ar.size
            if (order == 0){
                order =ar.size -1
            }else {
                order -=1
            }
            println(ar[order]);
            println(ar)
            ar.removeAt(order);
        }
    }

    val zuheResult = mutableSetOf<String>()
    fun zuhe(list: MutableList<Char>, start:Int,length:Int) {
        if (length == 1 || list.size == 1) {
            val key = list.joinToString("")
            if (!zuheResult.contains(key))  {
                zuheResult.add(key)
            }
        } else {
            for (i in start until start + length) {
                swap(list, start, i);
                zuhe(list, start + 1, length - 1);
                swap(list, start, i);//切记一定要换回，否则影响下次的循环交换。
            }
        }
    }
    fun swap(list: MutableList<Char>, start:Int, i:Int) {
        val temp = list[start]
        list[start] = list[i]
        list[i] = temp
    }

    private fun subsets(word: String): ArrayList<String>? {
        val s = ArrayList<String>()
        val length = word.length
        for (c in 0 until length) {
            for (i in 0 until length - c) {
                val sub = word.substring(c, c + i + 1)
                s.add(sub)
            }
        }
        return s
    }

}